//
// Created by zhouyi on 2020/7/8.
//

#include "TestBaseKnowledgePoint.h"

//  nullptr 关键字，专门用来区分空指针、0。nullptr 的类型为 nullptr_t
#define LEN 10
using namespace std;


constexpr int len_foo() {
    return 5;
}

constexpr int fibonacci(const int n) {
    return n == 1 || n == 2 ? 1 : fibonacci(n - 1) + fibonacci(n - 2);
}

//constexpr int fibonacci(const int n) {
//    if(n == 1) return 1;
//    if(n == 2) return 1;
//    return fibonacci(n-1)+fibonacci(n-2);
//}


template <typename... Args>
void magic(Args... args) {
    std::cout << sizeof...(args) << std::endl;
}


enum class new_enum : unsigned int {
    value1,
    value2,
    value3 = 100,
    value4 = 100
};

void learn_lambda_func_1() {
    int value_1 = 1;
    auto copy_value_1 = [value_1] {
        return value_1;
    };
    value_1 = 100;
    auto stored_value_1 = copy_value_1();
    // 这时, stored_value_1 == 1, 而 value_1 == 100.
    // 因为 copy_value_1 在创建时就保存了一份 value_1 的拷贝
    cout << "value_1 = " << value_1 << endl;
    cout << "stored_value_1 = " << stored_value_1 << endl;
}

void learn_lambda_func_2() {
    int value_2 = 1;
    auto copy_value_2 = [&value_2] {
        return value_2;
    };
    value_2 = 100;
    auto stored_value_2 = copy_value_2();
    // 这时, stored_value_2 == 100, value_1 == 100.
    // 因为 copy_value_2 保存的是引用
    cout << "value_2 = " << value_2 << endl;
    cout << "stored_value_2 = " << stored_value_2 << endl;
}

void learn_lambda_func_3(){
    auto important = std::make_unique<int>(1);
    auto add = [v1 = 1, v2 = std::move(important)](int x, int y) -> int {
        return x+y+v1+(*v2);
    };
    std::cout << "add(3, 4) = " << add(3, 4) << std::endl;
}

void learn_lambda_func_4(){
    auto generic = [](auto x, auto y) {
        return x+y;
    };

    std::cout << "generic(1,2) = " << generic(1, 2) << std::endl;
    std::cout << "generic(1.1,2.2) = " << generic(1.1, 2.2) << std::endl;
}

int main(int argc, char *argv[]) {
//    foo(0);

// foo(NULL); // 编译无法通过

//    foo(nullptr);


//    char arr_1[10];
//    char arr_2[LEN];
//    int len = 5;
//    char arr_3[len + 5];          // 非法
//    const int len_2 = 10;
//    char arr_4[len_2 + 5];        // 合法
//    char arr_5[len_foo() + 5];  // 非法

    int array[] = { 1, 2, 3, 4, 5 };
    for (auto &x : array) {
        std::cout << x << std::endl;
    }

    // 原始的写法
    std::vector <int> arr(5, 100);
    for (std::vector <int>::iterator i = arr.begin(); i != arr.end(); ++i) {
        std::cout << *i << std::endl;
    }
    // C++14写法
    // & 启用了引用, 如果没有则对 arr 中的元素只能读取不能修改
    for (auto &i : arr) {
        std::cout << i << std::endl;
    }

    magic();        // 输出0
    magic(1);       // 输出1
    magic(1, "");   // 输出2

    if (new_enum::value3 == new_enum::value4) {
        // 会输出
        std::cout << "new_enum::value3 == new_enum::value4" << std::endl;
    }



    return 0;


    return 0;
}